<?php
/**
 *+------------------
 * madong
 *+------------------
 * Copyright (c) https://gitee.com/motion-code  All rights reserved.
 *+------------------
 * Author: Mr. April (405784684@qq.com)
 *+------------------
 * Official Website: http://www.madong.tech
 */

namespace madong\webman\wf\services;

use madong\webman\wf\basic\BaseService;
use madong\ingenious\enums\ProcessConstEnum;
use madong\ingenious\interface\model\IProcessInstance;
use madong\ingenious\interface\model\IProcessInstanceHistory;
use madong\ingenious\interface\services\IProcessInstanceHistoryService;
use madong\ingenious\libs\utils\ArrayHelper;
use madong\ingenious\libs\utils\AssertHelper;
use madong\ingenious\libs\utils\Pagination;
use madong\ingenious\libs\utils\ProcessFlowUtils;
use madong\ingenious\libs\utils\PropertyCopier;
use madong\webman\wf\dao\ProcessInstanceHistoryDao;
use support\Container;

class ProcessInstanceHistoryService extends BaseService implements IProcessInstanceHistoryService
{

    public function __construct()
    {
        $this->dao = Container::make(ProcessInstanceHistoryDao::class);
    }

    public function created(object $param): ?IProcessInstanceHistory
    {
        unset($param->id);
        $model = $this->dao->getModel();
        PropertyCopier::copyProperties($param, $model);
        return $model->save();
    }

    public function updated(object $param): bool
    {
        AssertHelper::notNull($param->id ?? '', '参数ID不能为空');
        $model = $this->dao->get($param->id);
        PropertyCopier::copyProperties($param, $model);
        return $model->save();
    }

    public function list(object $param): array
    {
        $where = ArrayHelper::paramsFilter($param, [
            ['parent_id', ''],
            ['process_define_id', ''],
            ['state', ''],
            ['parent_node_name', ''],
            ['business_no', ''],
            ['operator', ''],
            ['display_name', ''],
        ]);
        [$page, $limit] = Pagination::getPageValue($param);
        $items = $this->dao->selectList($where, '*', $page, $limit, 'create_time', ['define' => function ($query) use ($where) {
            $map = ['display_name'];
            foreach ($where as $key => $value) {
                if (in_array($key, $map) && !empty($value)) {
                    $query->where($key, $value);
                }
            }
        }], true)->toArray();
        $total = $this->dao->count($where, true);
        foreach ($items as $key => $value) {
            $items[$key]['process_name'] = $value['define']['display_name'] ?? '';
            $items[$key]['ext']          = $value['variable'];
            $items[$key]['form_data']    = ProcessFlowUtils::filterObjectByPrefix((object)$value['variable'], 'f_');
            $items[$key]['variable']     = json_encode($value['variable']);
        }
        return compact('items', 'total');
    }

    public function findById(string $id): ?IProcessInstanceHistory
    {
        AssertHelper::notNull($id, '参数ID不能为空');
        $model = $this->dao->get($id, ['*'], ['define']);
        if ($model != null) {
            $processDefine = $model->getData('define');
            $content       = ArrayHelper::arrayToObject($processDefine->getData('content') ?? []);
            $model->set('version', $processDefine->getData('version'));
            $model->set('json_object', $content);
            $model->set('ext', $model->getData('variable'));
            $model->set('form_data', ProcessFlowUtils::filterObjectByPrefix($model->getData('variable'), ProcessConstEnum::FORM_DATA_PREFIX->value));
            $model->set('variable', json_encode($model->getData('variable')));
            $model->hidden(['define']);
        }
        return $model;
    }

    /**
     * 根据实例创建历史记录
     *
     * @param \madong\ingenious\interface\model\IProcessInstance $param
     *
     * @return bool
     */
    public function createHistoryProcessInstance(IProcessInstance $param): bool
    {
        $model = $this->dao->getModel();
        PropertyCopier::copyProperties((object)$param->toArray(), $model);
        return $model->save();
    }
}
